package com.mmc.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mmc.common.result.Result;
import com.mmc.entity.User;
import com.mmc.entity.Role;
import com.mmc.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.io.File;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 用户控制器
 *
 * @author kunfe
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@SaCheckLogin
@Tag(name = "用户管理", description = "用户管理相关接口")
public class UserController {

    private final UserService userService;

    @Operation(summary = "分页查询用户")
    @GetMapping("/page")
    public Result<Page<User>> getUserPage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String realName,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String email,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Long deptId) {
        
        Page<User> page = new Page<>(current, size);
        Page<User> result = userService.getUserPage(page, username, realName, phone, email, status, deptId);
        
        return Result.ok(result);
    }

    @Operation(summary = "获取用户详情")
    @GetMapping("/{id}")
    public Result<User> getUserById(@PathVariable Long id) {
        User user = userService.getById(id);
        if (user != null) {
            user.setRoleIds(userService.getUserRoleIds(id));
        }
        return Result.ok(user);
    }

    @Operation(summary = "获取用户列表")
    @GetMapping("/list")
    public Result<List<User>> getUserList() {
        List<User> users = userService.list(new LambdaQueryWrapper<User>()
                .eq(User::getStatus, 1)
                .orderByAsc(User::getRealName));
        return Result.ok(users);
    }

    @Operation(summary = "新增用户")
    @PostMapping
    public Result<Void> createUser(@Valid @RequestBody CreateUserRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(request.getPassword());
        user.setRealName(request.getRealName());
        user.setNickname(request.getNickname());
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setGender(request.getGender());
        user.setBirthday(request.getBirthday());
        user.setDeptId(request.getDeptId());
        user.setPosition(request.getPosition());
        user.setIntro(request.getIntro());
        user.setStatus(request.getStatus());
        user.setUserType(request.getUserType());
        user.setRemark(request.getRemark());
        user.setRoleIds(request.getRoleIds());
        
        boolean success = userService.createUser(user);
        return success ? Result.ok() : Result.fail("新增失败");
    }

    @Operation(summary = "更新用户")
    @PutMapping("/{id}")
    public Result<Void> updateUser(@PathVariable Long id, @Valid @RequestBody UpdateUserRequest request) {
        User user = new User();
        user.setId(id);
        user.setUsername(request.getUsername());
        user.setPassword(request.getPassword());
        user.setRealName(request.getRealName());
        user.setNickname(request.getNickname());
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setGender(request.getGender());
        user.setBirthday(request.getBirthday());
        user.setDeptId(request.getDeptId());
        user.setPosition(request.getPosition());
        user.setIntro(request.getIntro());
        user.setStatus(request.getStatus());
        user.setUserType(request.getUserType());
        user.setRemark(request.getRemark());
        user.setRoleIds(request.getRoleIds());
        
        boolean success = userService.updateUser(user);
        return success ? Result.ok() : Result.fail("更新失败");
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/{id}")
    public Result<Void> deleteUser(@PathVariable Long id) {
        boolean success = userService.deleteUser(id);
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "批量删除用户")
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteUser(@Valid @RequestBody BatchDeleteRequest request) {
        boolean success = userService.batchDeleteUser(request.getIds());
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "启用/禁用用户")
    @PutMapping("/{id}/status")
    public Result<Void> changeStatus(@PathVariable Long id, @RequestBody ChangeStatusRequest request) {
        boolean success = userService.changeStatus(id, request.getStatus());
        return success ? Result.ok() : Result.fail("操作失败");
    }

    @Operation(summary = "重置密码")
    @PutMapping("/{id}/reset-password")
    public Result<Void> resetPassword(@PathVariable Long id, @Valid @RequestBody ResetPasswordRequest request) {
        boolean success = userService.resetPassword(id, request.getNewPassword());
        return success ? Result.ok() : Result.fail("重置失败");
    }

    @Operation(summary = "修改密码")
    @PutMapping("/change-password")
    public Result<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = userService.changePassword(userId, request.getOldPassword(), request.getNewPassword());
        return success ? Result.ok() : Result.fail("修改失败");
    }

    @Operation(summary = "分配角色")
    @PutMapping("/{id}/roles")
    public Result<Void> assignRoles(@PathVariable Long id, @Valid @RequestBody AssignRolesRequest request) {
        boolean success = userService.assignRoles(id, request.getRoleIds());
        return success ? Result.ok() : Result.fail("分配失败");
    }

    @Operation(summary = "获取用户角色")
    @GetMapping("/{id}/roles")
    public Result<List<Role>> getUserRoles(@PathVariable Long id) {
        List<Role> roles = userService.getUserRoles(id);
        return Result.ok(roles);
    }

    @Operation(summary = "更新个人信息")
    @PutMapping("/profile")
    public Result<Void> updateProfile(@Valid @RequestBody UpdateProfileRequest request) {
        Long userId = StpUtil.getLoginIdAsLong();
        User user = new User();
        user.setRealName(request.getRealName());
        user.setNickname(request.getNickname());
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setGender(request.getGender());
        user.setBirthday(request.getBirthday());
        user.setIntro(request.getIntro());
        
        boolean success = userService.updateProfile(userId, user);
        return success ? Result.ok() : Result.fail("更新失败");
    }

    @Operation(summary = "上传头像")
    @PostMapping("/avatar")
    public Result<String> uploadAvatar(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return Result.fail("上传文件不能为空");
            }
            
            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return Result.fail("只能上传图片文件");
            }
            
            // 检查文件大小（5MB）
            if (file.getSize() > 5 * 1024 * 1024) {
                return Result.fail("文件大小不能超过5MB");
            }
            
            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")) : ".jpg";
            String fileName = System.currentTimeMillis() + extension;
            
            // 创建上传目录
            String uploadDir = "./upload/avatar/";
            File dir = new File(uploadDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            // 保存文件
            File targetFile = new File(uploadDir + fileName);
            file.transferTo(targetFile);
            
            String avatarUrl = "/api/file/avatar/" + fileName;
            
            Long userId = StpUtil.getLoginIdAsLong();
            userService.updateAvatar(userId, avatarUrl);
            
            return Result.ok(avatarUrl);
        } catch (Exception e) {
            log.error("上传头像失败", e);
            return Result.fail("上传失败：" + e.getMessage());
        }
    }

    @Operation(summary = "导入用户")
    @PostMapping("/import")
    public Result<Void> importUsers(@RequestParam("file") MultipartFile file) {
        // TODO: 实现Excel导入逻辑
        return Result.ok();
    }

    @Operation(summary = "导出用户")
    @GetMapping("/export")
    public Result<Void> exportUsers(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String realName,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String email,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Long deptId) {
        
        List<User> users = userService.exportUsers(username, realName, phone, email, status, deptId);
        // TODO: 实现Excel导出逻辑
        
        return Result.ok();
    }

    // DTO类
    @Data
    public static class CreateUserRequest {
        @NotBlank(message = "用户名不能为空")
        private String username;
        
        @NotBlank(message = "密码不能为空")
        private String password;
        
        @NotBlank(message = "真实姓名不能为空")
        private String realName;
        
        private String nickname;
        private String email;
        private String phone;
        private Integer gender;
        private String birthday;
        private Long deptId;
        private String position;
        private String intro;
        private Integer status = 1;
        private Integer userType = 1;
        private String remark;
        private List<Long> roleIds;
    }

    @Data
    public static class UpdateUserRequest {
        @NotBlank(message = "用户名不能为空")
        private String username;
        
        private String password;
        
        @NotBlank(message = "真实姓名不能为空")
        private String realName;
        
        private String nickname;
        private String email;
        private String phone;
        private Integer gender;
        private String birthday;
        private Long deptId;
        private String position;
        private String intro;
        private Integer status;
        private Integer userType;
        private String remark;
        private List<Long> roleIds;
    }

    @Data
    public static class BatchDeleteRequest {
        @NotEmpty(message = "删除ID列表不能为空")
        private List<Long> ids;
    }

    @Data
    public static class ChangeStatusRequest {
        @NotNull(message = "状态不能为空")
        private Integer status;
    }

    @Data
    public static class ResetPasswordRequest {
        @NotBlank(message = "新密码不能为空")
        private String newPassword;
    }

    @Data
    public static class ChangePasswordRequest {
        @NotBlank(message = "原密码不能为空")
        private String oldPassword;
        
        @NotBlank(message = "新密码不能为空")
        private String newPassword;
    }

    @Data
    public static class AssignRolesRequest {
        private List<Long> roleIds;
    }

    @Data
    public static class UpdateProfileRequest {
        private String realName;
        private String nickname;
        private String email;
        private String phone;
        private Integer gender;
        private String birthday;
        private String intro;
    }
} 